home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Tool Chest / Development Tools & Languages / Dylan Related / Mindy / Mindy 1.2 - portable sources / interp / buf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-15  |  4.8 KB  |  178 lines  |  [TEXT/ttxt]

  1. /**********************************************************************\
  2. *
  3. *  Copyright (c) 1994  Carnegie Mellon University
  4. *  All rights reserved.
  5. *  
  6. *  Use and copying of this software and preparation of derivative
  7. *  works based on this software are permitted, including commercial
  8. *  use, provided that the following conditions are observed:
  9. *  
  10. *  1. This copyright notice must be retained in full on any copies
  11. *     and on appropriate parts of any derivative works.
  12. *  2. Documentation (paper or online) accompanying any system that
  13. *     incorporates this software, or any part of it, must acknowledge
  14. *     the contribution of the Gwydion Project at Carnegie Mellon
  15. *     University.
  16. *  
  17. *  This software is made available "as is".  Neither the authors nor
  18. *  Carnegie Mellon University make any warranty about the software,
  19. *  its performance, or its conformity to any specification.
  20. *  
  21. *  Bug reports, questions, comments, and suggestions should be sent by
  22. *  E-mail to the Internet address "gwydion-bugs@cs.cmu.edu".
  23. *
  24. ***********************************************************************
  25. *
  26. * $Header: buf.c,v 1.11 94/11/29 06:43:02 wlott Exp $
  27. *
  28. * This file implements buffers, a special byte vector used by streams.
  29. *
  30. \**********************************************************************/
  31.  
  32. #include "../compat/std-c.h"
  33.  
  34. #include "mindy.h"
  35. #include "gc.h"
  36. #include "coll.h"
  37. #include "class.h"
  38. #include "module.h"
  39. #include "num.h"
  40. #include "bool.h"
  41. #include "obj.h"
  42. #include "error.h"
  43. #include "list.h"
  44. #include "def.h"
  45. #include "sym.h"
  46. #include "type.h"
  47. #include "vec.h"
  48. #include "str.h"
  49. #include "buf.h"
  50.  
  51. #define max(a,b) ((a)>(b) ? (a) : (b))
  52.  
  53. obj_t obj_BufferClass = NULL;
  54.  
  55. static obj_t dylan_buffer_make(obj_t class, obj_t size)
  56. {
  57.     int len;
  58.     obj_t res;
  59.  
  60.     len = fixnum_value(check_type(size, obj_FixnumClass));
  61.  
  62.     if (len < 0)
  63.     error("Bogus size: for make %=: %d", class, size);
  64.  
  65.     res = alloc(obj_BufferClass, sizeof(struct buffer) 
  66.       + max(len - sizeof(((struct buffer *)res)->data),
  67.         sizeof(((struct buffer *)res)->data)));
  68.  
  69.     obj_ptr(struct buffer *, res)->length = len;
  70.  
  71.     return res;
  72. }
  73.  
  74. static obj_t dylan_buffer_size(obj_t buffer)
  75. {
  76.     return make_fixnum(obj_ptr(struct buffer *, buffer)->length);
  77. }
  78.  
  79. static obj_t dylan_buffer_element(obj_t buffer, obj_t index, obj_t def)
  80. {
  81.     int i = fixnum_value(index);
  82.  
  83.     if (0 <= i && i < obj_ptr(struct buffer *, buffer)->length)
  84.     return make_fixnum(buffer_data(buffer)[i]);
  85.     else if (def != obj_Unbound)
  86.     return def;
  87.     else {
  88.     error("No element %= in %=", index, buffer);
  89.     return NULL;
  90.     }
  91. }
  92.  
  93. static obj_t dylan_buffer_element_setter(obj_t val, obj_t buffer, obj_t index)
  94. {
  95.     int i = fixnum_value(index);
  96.  
  97.     if (0 <= i && i < obj_ptr(struct buffer *, buffer)->length)
  98.     buffer_data(buffer)[i] = fixnum_value(val);
  99.     else
  100.     error("No element %= in %=", index, buffer);
  101.  
  102.     return val;
  103. }
  104.  
  105. static obj_t dylan_memcpy(obj_t dst, obj_t dst_off, obj_t src, obj_t src_off,
  106.               obj_t count)
  107. {
  108.     memmove(buffer_data(dst) + fixnum_value(dst_off),
  109.         buffer_data(src) + fixnum_value(src_off),
  110.         fixnum_value(count));
  111.     return dst;
  112. }
  113.  
  114.  
  115. /* GC stuff. */
  116.  
  117. static int scav_buffer(struct object *ptr)
  118. {
  119.     struct buffer *buffer = (struct buffer *)ptr;
  120.  
  121.     return sizeof(struct buffer) + max(buffer->length - sizeof(buffer->data),
  122.                        sizeof(buffer->data));
  123. }
  124.  
  125. static obj_t trans_buffer(obj_t buffer)
  126. {
  127.     return transport(buffer,
  128.              sizeof(struct buffer)
  129.              + max(obj_ptr(struct buffer *, buffer)->length
  130.                - sizeof(((struct buffer *)buffer)->data),
  131.                sizeof(((struct buffer *)buffer)->data)));
  132. }
  133.  
  134. void scavenge_buffer_roots(void)
  135. {
  136.     scavenge(&obj_BufferClass);
  137. }
  138.  
  139.  
  140.  
  141. /* Init stuff. */
  142.  
  143. void make_buffer_classes(void)
  144. {
  145.     obj_BufferClass = make_builtin_class(scav_buffer, trans_buffer);
  146. }
  147.  
  148. void init_buffer_classes(void)
  149. {
  150.     init_builtin_class(obj_BufferClass, "<buffer>", obj_VectorClass, NULL);
  151. }
  152.  
  153. void init_buffer_functions(void)
  154. {
  155.     obj_t u;
  156.  
  157.     define_method("element", list2(obj_BufferClass, obj_FixnumClass),
  158.           FALSE, list1(pair(symbol("default"), obj_Unbound)), FALSE,
  159.           obj_FixnumClass, dylan_buffer_element);
  160.     define_method("element-setter",
  161.           list3(obj_FixnumClass, obj_BufferClass,
  162.             obj_FixnumClass),
  163.           FALSE, obj_False, FALSE, obj_ObjectClass,
  164.           dylan_buffer_element_setter);
  165.     define_method("size", list1(obj_BufferClass), FALSE, obj_False, FALSE,
  166.           obj_FixnumClass, dylan_buffer_size);
  167.     define_method("make", list1(singleton(obj_BufferClass)), FALSE,
  168.           list1(pair(symbol("size"), make_fixnum(4096))),
  169.           FALSE, obj_BufferClass, dylan_buffer_make);
  170.  
  171.     u = type_union(obj_ByteStringClass, obj_ByteVectorClass);
  172.     u = type_union(u, obj_BufferClass);
  173.     define_method("copy-bytes",
  174.           listn(5, u, obj_FixnumClass, u,
  175.             obj_FixnumClass, obj_FixnumClass),
  176.           FALSE, obj_False, FALSE, u, dylan_memcpy);
  177. }
  178.